using Microsoft.Extensions.Logging;
using Mark.Services.Interfaces;
using System.Text.Json;
using MarkFileInfo = Mark.Models.FileInfo;

namespace Mark.Services;

/// <summary>
/// WebView JavaScript Bridge 服务
/// </summary>
public class WebViewBridge
{
    private readonly IChatService _chatService;
    private readonly ILogger<WebViewBridge> _logger;
    private WebView? _webView;

    public WebViewBridge(IChatService chatService, ILogger<WebViewBridge> logger)
    {
        _chatService = chatService;
        _logger = logger;
    }

    /// <summary>
    /// 设置WebView引用
    /// </summary>
    public void SetWebView(WebView webView)
    {
        _webView = webView;
    }

    #region 供C#调用的方法

    /// <summary>
    /// 创建对话
    /// </summary>
    public async Task<string> CreateConversationAsync(string userId, string title, string? description = null)
    {
        try
        {
            var conversation = await _chatService.CreateConversationAsync(userId, title, description);
            return JsonSerializer.Serialize(new { success = true, data = conversation });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error creating conversation");
            return JsonSerializer.Serialize(new { success = false, message = ex.Message });
        }
    }

    /// <summary>
    /// 获取用户对话列表
    /// </summary>
    public async Task<string> GetUserConversationsAsync(string userId)
    {
        try
        {
            var conversations = await _chatService.GetUserConversationsAsync(userId);
            return JsonSerializer.Serialize(new { success = true, data = conversations });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting user conversations");
            return JsonSerializer.Serialize(new { success = false, message = ex.Message });
        }
    }

    /// <summary>
    /// 发送消息
    /// </summary>
    public async Task<string> SendMessageAsync(string conversationId, string content, string role = "user", string? modelId = null)
    {
        try
        {
            var message = await _chatService.SendMessageAsync(conversationId, content, role, modelId);
            return JsonSerializer.Serialize(new { success = true, data = message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error sending message");
            return JsonSerializer.Serialize(new { success = false, message = ex.Message });
        }
    }

    /// <summary>
    /// 获取对话消息
    /// </summary>
    public async Task<string> GetConversationMessagesAsync(string conversationId)
    {
        try
        {
            var messages = await _chatService.GetConversationMessagesAsync(conversationId);
            return JsonSerializer.Serialize(new { success = true, data = messages });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting conversation messages");
            return JsonSerializer.Serialize(new { success = false, message = ex.Message });
        }
    }

    /// <summary>
    /// 生成AI响应
    /// </summary>
    public async Task<string> GenerateResponseAsync(string conversationId, string modelId)
    {
        try
        {
            var response = await _chatService.GenerateResponseAsync(conversationId, modelId);
            
            // 通知前端新消息
            await NotifyNewMessage(response);
            
            return JsonSerializer.Serialize(new { success = true, data = response });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error generating response");
            return JsonSerializer.Serialize(new { success = false, message = ex.Message });
        }
    }

    /// <summary>
    /// 上传文件
    /// </summary>
    public async Task<string> UploadFileAsync(string userId, string fileName, string mimeType, byte[] fileData)
    {
        try
        {
            using var stream = new MemoryStream(fileData);
            var fileInfo = await _chatService.UploadFileAsync(userId, stream, fileName, mimeType);
            return JsonSerializer.Serialize(new { success = true, data = fileInfo });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error uploading file");
            return JsonSerializer.Serialize(new { success = false, message = ex.Message });
        }
    }

    #endregion

    #region 处理来自前端的JavaScript调用

    /// <summary>
    /// 处理来自前端的JavaScript调用
    /// </summary>
    public async Task<string> HandleJavaScriptCall(string method, string parameters)
    {
        try
        {
            _logger.LogDebug($"Handling JavaScript call: {method} with parameters: {parameters}");
            
            var paramDict = JsonSerializer.Deserialize<Dictionary<string, object>>(parameters) ?? new Dictionary<string, object>();

            return method switch
            {
                "createConversation" => await CreateConversationAsync(
                    paramDict.GetValueOrDefault("userId")?.ToString() ?? "",
                    paramDict.GetValueOrDefault("title")?.ToString() ?? "",
                    paramDict.GetValueOrDefault("description")?.ToString()),
                    
                "getUserConversations" => await GetUserConversationsAsync(
                    paramDict.GetValueOrDefault("userId")?.ToString() ?? ""),
                    
                "sendMessage" => await SendMessageAsync(
                    paramDict.GetValueOrDefault("conversationId")?.ToString() ?? "",
                    paramDict.GetValueOrDefault("content")?.ToString() ?? "",
                    paramDict.GetValueOrDefault("role")?.ToString() ?? "user",
                    paramDict.GetValueOrDefault("modelId")?.ToString()),
                    
                "getConversationMessages" => await GetConversationMessagesAsync(
                    paramDict.GetValueOrDefault("conversationId")?.ToString() ?? ""),
                    
                "generateResponse" => await GenerateResponseAsync(
                    paramDict.GetValueOrDefault("conversationId")?.ToString() ?? "",
                    paramDict.GetValueOrDefault("modelId")?.ToString() ?? ""),
                    
                _ => JsonSerializer.Serialize(new { success = false, message = $"Unknown method: {method}" })
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error handling JavaScript call: {method}");
            return JsonSerializer.Serialize(new { success = false, message = ex.Message });
        }
    }

    #endregion

    #region 向前端发送通知的方法

    /// <summary>
    /// 通知前端新消息
    /// </summary>
    public async Task NotifyNewMessage(Models.Message message)
    {
        if (_webView == null) return;

        try
        {
            var messageJson = JsonSerializer.Serialize(message);
            var script = $"window.onNewMessage && window.onNewMessage({messageJson});";
            await _webView.EvaluateJavaScriptAsync(script);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error notifying new message");
        }
    }

    /// <summary>
    /// 通知前端对话更新
    /// </summary>
    public async Task NotifyConversationUpdated(Models.Conversation conversation)
    {
        if (_webView == null) return;

        try
        {
            var conversationJson = JsonSerializer.Serialize(conversation);
            var script = $"window.onConversationUpdated && window.onConversationUpdated({conversationJson});";
            await _webView.EvaluateJavaScriptAsync(script);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error notifying conversation updated");
        }
    }

    /// <summary>
    /// 通知前端错误
    /// </summary>
    public async Task NotifyError(string message)
    {
        if (_webView == null) return;

        try
        {
            var errorJson = JsonSerializer.Serialize(new { message });
            var script = $"window.onError && window.onError({errorJson});";
            await _webView.EvaluateJavaScriptAsync(script);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error notifying error");
        }
    }

    #endregion

    #region 初始化JavaScript接口

    /// <summary>
    /// 获取JavaScript接口代码
    /// </summary>
    public string GetJavaScriptInterface()
    {
        return @"
window.MarkAPI = {
    // 调用C#方法的通用函数
    _callCSharp: async function(method, parameters) {
        try {
            // 通过注入的bridge对象调用C#方法
            const result = await window.bridge.handleJavaScriptCall(method, JSON.stringify(parameters || {}));
            return JSON.parse(result);
        } catch (error) {
            console.error('Call to C# failed:', error);
            return { success: false, message: error.message };
        }
    },

    // 创建对话
    createConversation: async function(userId, title, description) {
        return await this._callCSharp('createConversation', { userId, title, description });
    },

    // 获取用户对话列表
    getUserConversations: async function(userId) {
        return await this._callCSharp('getUserConversations', { userId });
    },

    // 发送消息
    sendMessage: async function(conversationId, content, role, modelId) {
        return await this._callCSharp('sendMessage', { conversationId, content, role: role || 'user', modelId });
    },

    // 获取对话消息
    getConversationMessages: async function(conversationId) {
        return await this._callCSharp('getConversationMessages', { conversationId });
    },

    // 生成AI响应
    generateResponse: async function(conversationId, modelId) {
        return await this._callCSharp('generateResponse', { conversationId, modelId });
    },

    // 上传文件（暂时未实现）
    uploadFile: async function(userId, file) {
        console.warn('File upload not yet implemented in MAUI WebView');
        return { success: false, message: 'File upload not yet implemented' };
    }
};

// 事件回调函数（由前端应用实现）
// window.onNewMessage = function(message) { ... };
// window.onConversationUpdated = function(conversation) { ... };
// window.onError = function(error) { ... };

console.log('Mark API initialized successfully for MAUI');
";
    }

    #endregion
} 